<template>
  <div class="multi-file-uploader">
    <el-card class="upload-card">
      <template #header>
        <div class="card-header">
          <span>多文件上传</span>
          <div class="header-actions">
            <el-badge :value="fileList.length" :hidden="fileList.length === 0" type="primary">
              <el-button size="small" @click="showFileList = !showFileList">
                文件列表
              </el-button>
            </el-badge>
          </div>
        </div>
      </template>

      <!-- 文件选择区域 -->
      <div class="upload-area" @click="selectFiles" @drop="handleDrop" @dragover.prevent @dragenter.prevent>
        <el-icon class="upload-icon" size="48">
          <UploadFilled />
        </el-icon>
        <div class="upload-text">
          <p>点击选择文件或拖拽文件到这里</p>
          <p class="upload-hint">支持多文件选择，支持大文件上传，断点续传</p>
        </div>
        <input
          ref="fileInput"
          type="file"
          multiple
          style="display: none"
          @change="handleFileSelect"
        />
      </div>

      <!-- 总体进度 -->
      <div v-if="totalProgress.total > 0" class="total-progress">
        <div class="progress-header">
          <span>总体进度：{{ totalProgress.completed }}/{{ totalProgress.total }} 个文件</span>
          <span class="progress-stats">
            上传中：{{ totalProgress.uploading }} | 失败：{{ totalProgress.failed }}
          </span>
        </div>
        <el-progress
          :percentage="totalProgress.progress"
          :format="() => `${totalProgress.progress}%`"
          :status="getProgressStatus()"
        />
      </div>

      <!-- 批量操作 -->
      <div v-if="fileList.length > 0" class="batch-controls">
        <el-button
          type="primary"
          @click="startAllUploads"
          :disabled="!hasWaitingFiles"
          :loading="isUploading"
        >
          开始全部上传
        </el-button>
        
        <el-button
          type="warning"
          @click="pauseAllUploads"
          :disabled="!hasUploadingFiles"
        >
          暂停全部
        </el-button>
        
        <el-button
          type="success"
          @click="resumeAllUploads"
          :disabled="!hasPausedFiles"
        >
          恢复全部
        </el-button>
        
        <el-button
          type="danger"
          @click="clearAllFiles"
        >
          清空列表
        </el-button>
      </div>

      <!-- 状态提示 -->
      <div v-if="statusMessage" class="status-message">
        <el-alert
          :title="statusMessage"
          :type="getAlertType()"
          :closable="true"
          @close="statusMessage = ''"
          show-icon
        />
      </div>
    </el-card>

    <!-- 文件列表 -->
    <el-card v-if="showFileList && fileList.length > 0" class="file-list-card">
      <template #header>
        <div class="card-header">
          <span>文件列表 ({{ fileList.length }})</span>
          <el-button size="small" @click="showFileList = false">收起</el-button>
        </div>
      </template>

      <div class="file-list">
        <div
          v-for="file in fileList"
          :key="file.id"
          class="file-item"
          :class="getFileItemClass(file.status)"
        >
          <div class="file-info">
            <div class="file-header">
              <el-icon class="file-icon">
                <Document />
              </el-icon>
              <div class="file-details">
                <div class="file-name" :title="file.name">{{ file.name }}</div>
                <div class="file-meta">
                  {{ formatFileSize(file.size) }} | {{ getStatusText(file.status) }}
                </div>
              </div>
              <div class="file-actions">
                <el-button
                  v-if="file.status === 'waiting'"
                  size="small"
                  type="primary"
                  @click="startSingleUpload(file.id)"
                >
                  开始
                </el-button>
                <el-button
                  v-if="file.status === 'uploading'"
                  size="small"
                  type="warning"
                  @click="pauseSingleUpload(file.id)"
                >
                  暂停
                </el-button>
                <el-button
                  v-if="file.status === 'paused'"
                  size="small"
                  type="success"
                  @click="resumeSingleUpload(file.id)"
                >
                  恢复
                </el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="removeFile(file.id)"
                >
                  删除
                </el-button>
              </div>
            </div>

            <!-- 进度条 -->
            <div v-if="file.status !== 'waiting'" class="file-progress">
              <el-progress
                :percentage="file.progress"
                :format="() => getProgressText(file)"
                :status="getFileProgressStatus(file.status)"
                :stroke-width="6"
              />
            </div>

            <!-- 错误信息 -->
            <div v-if="file.status === 'failed' && file.error" class="file-error">
              <el-alert
                :title="file.error"
                type="error"
                :closable="false"
                size="small"
              />
            </div>

            <!-- 上传详情 -->
            <div v-if="file.status === 'uploading' && file.chunks.length > 0" class="upload-details">
              <span>分片进度：{{ file.uploadedChunks.length }}/{{ file.chunks.length }}</span>
              <span v-if="file.startTime">速度：{{ calculateSpeed(file) }}</span>
            </div>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { UploadFilled, Document } from '@element-plus/icons-vue'
import { MultiFileUploadManager } from '../utils/upload.js'

export default {
  name: 'MultiFileUploader',
  components: {
    UploadFilled,
    Document
  },
  setup() {
    // 响应式数据
    const fileInput = ref(null)
    const fileList = ref([])
    const showFileList = ref(false)
    const statusMessage = ref('')
    const isUploading = ref(false)
    
    // 上传管理器
    let uploadManager = null

    // 计算属性
    const totalProgress = computed(() => {
      if (!uploadManager) return { progress: 0, completed: 0, total: 0, uploading: 0, failed: 0 }
      return uploadManager.getTotalProgress()
    })

    const hasWaitingFiles = computed(() => {
      return fileList.value.some(f => f.status === 'waiting')
    })

    const hasUploadingFiles = computed(() => {
      return fileList.value.some(f => f.status === 'uploading')
    })

    const hasPausedFiles = computed(() => {
      return fileList.value.some(f => f.status === 'paused')
    })

    // 初始化上传管理器
    const initUploadManager = () => {
      uploadManager = new MultiFileUploadManager({
        concurrencyLimit: 2, // 同时上传2个文件
        chunkConcurrency: 3, // 每个文件3个分片并发
        onFileProgress: (fileId, progressData) => {
          updateFileProgress(fileId, progressData)
        },
        onError: (fileId, error) => {
          console.error(`文件上传失败 ${fileId}:`, error)
          ElMessage.error(`文件上传失败: ${error.message}`)
        },
        onComplete: (allFiles) => {
          // 强制更新所有文件状态
          allFiles.forEach(file => {
            const fileIndex = fileList.value.findIndex(f => f.id === file.id)
            if (fileIndex !== -1) {
              fileList.value[fileIndex] = { ...fileList.value[fileIndex], ...file }
            }
          })
          
          const completed = allFiles.filter(f => f.status === 'completed').length
          const failed = allFiles.filter(f => f.status === 'failed').length
          
          if (failed === 0) {
            statusMessage.value = `全部上传完成！成功：${completed} 个文件`
            ElMessage.success(`全部上传完成！成功：${completed} 个文件`)
          } else {
            statusMessage.value = `上传完成！成功：${completed} 个，失败：${failed} 个`
            ElMessage.warning(`上传完成！成功：${completed} 个，失败：${failed} 个`)
          }
          isUploading.value = false
        }
      })
    }

    // 方法
    const selectFiles = () => {
      // 清空文件输入框的值，确保选择相同文件时也能触发change事件
      if (fileInput.value) {
        fileInput.value.value = ''
      }
      fileInput.value.click()
    }

    const handleFileSelect = (event) => {
      const files = Array.from(event.target.files)
      if (files.length > 0) {
        handleFiles(files)
      }
      // 清空input，允许重复选择同一文件
      event.target.value = ''
    }

    const handleDrop = (event) => {
      event.preventDefault()
      const files = Array.from(event.dataTransfer.files)
      if (files.length > 0) {
        handleFiles(files)
      }
    }

    const handleFiles = (files) => {
      if (!uploadManager) {
        initUploadManager()
      }

      files.forEach(file => {
        // 检查文件大小限制（可选）
        if (file.size > 100 * 1024 * 1024 * 1024) { // 100GB
          ElMessage.error(`文件 ${file.name} 过大，最大支持100GB`)
          return
        }

        const fileId = uploadManager.addFile(file)
        const fileData = uploadManager.getFile(fileId)
        fileList.value.push(fileData)
      })

      showFileList.value = true
      statusMessage.value = `已添加 ${files.length} 个文件到上传队列`
    }

    const updateFileProgress = (fileId, progressData) => {
      const fileIndex = fileList.value.findIndex(f => f.id === fileId)
      if (fileIndex !== -1) {
        const file = fileList.value[fileIndex]
        const updatedFile = uploadManager.getFile(fileId)
        
        // 更新文件数据 - 使用Vue的响应式更新
        fileList.value[fileIndex] = { ...file, ...updatedFile }
        
        // 如果有明确的状态更新，优先使用
        if (progressData.status) {
          fileList.value[fileIndex].status = progressData.status
        }
        if (progressData.progress !== undefined) {
          fileList.value[fileIndex].progress = progressData.progress
        }

        // 调试日志
        console.log(`文件 ${fileId} 状态更新:`, {
          type: progressData.type,
          status: updatedFile.status,
          progress: updatedFile.progress
        })

        if (progressData.type === 'completed') {
          ElMessage.success(`${file.name} ${progressData.message}`)
        } else if (progressData.type === 'md5') {
          // MD5计算进度可以在这里处理
        }
      }
    }

    const startAllUploads = async () => {
      if (!uploadManager || fileList.value.length === 0) return
      
      isUploading.value = true
      statusMessage.value = '开始批量上传...'
      
      try {
        await uploadManager.startAllUploads()
      } catch (error) {
        console.error('批量上传失败:', error)
        isUploading.value = false
      }
    }

    const pauseAllUploads = () => {
      if (!uploadManager) return
      uploadManager.pauseAllUploads()
      statusMessage.value = '已暂停所有上传'
    }

    const resumeAllUploads = () => {
      if (!uploadManager) return
      uploadManager.resumeAllUploads()
      statusMessage.value = '已恢复所有上传'
    }

    const startSingleUpload = (fileId) => {
      if (!uploadManager) return
      const file = uploadManager.getFile(fileId)
      if (file) {
        uploadManager.enqueueFileUpload(fileId)
      }
    }

    const pauseSingleUpload = (fileId) => {
      if (!uploadManager) return
      const file = uploadManager.getFile(fileId)
      if (file && file.status === 'uploading') {
        file.status = 'paused'
        updateFileProgress(fileId, { type: 'paused' })
      }
    }

    const resumeSingleUpload = (fileId) => {
      if (!uploadManager) return
      const file = uploadManager.getFile(fileId)
      if (file && file.status === 'paused') {
        file.status = 'waiting'
        uploadManager.enqueueFileUpload(fileId)
      }
    }

    const removeFile = async (fileId) => {
      try {
        await ElMessageBox.confirm('确定要删除这个文件吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })

        if (uploadManager) {
          uploadManager.removeFile(fileId)
        }
        
        const fileIndex = fileList.value.findIndex(f => f.id === fileId)
        if (fileIndex !== -1) {
          fileList.value.splice(fileIndex, 1)
        }
      } catch {
        // 用户取消删除
      }
    }

    const clearAllFiles = async () => {
      try {
        await ElMessageBox.confirm('确定要清空所有文件吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })

        fileList.value = []
        if (uploadManager) {
          uploadManager.files.clear()
        }
        statusMessage.value = '已清空文件列表'
      } catch {
        // 用户取消
      }
    }

    const formatFileSize = (bytes) => {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }

    const getStatusText = (status) => {
      const statusMap = {
        waiting: '等待中',
        calculating: '计算中',
        uploading: '上传中',
        paused: '已暂停',
        completed: '已完成',
        failed: '失败'
      }
      return statusMap[status] || status
    }

    const getFileItemClass = (status) => {
      return {
        'file-waiting': status === 'waiting',
        'file-calculating': status === 'calculating',
        'file-uploading': status === 'uploading',
        'file-paused': status === 'paused',
        'file-completed': status === 'completed',
        'file-failed': status === 'failed'
      }
    }

    const getProgressStatus = () => {
      if (totalProgress.value.failed > 0) return 'exception'
      if (totalProgress.value.completed === totalProgress.value.total && totalProgress.value.total > 0) return 'success'
      return ''
    }

    const getFileProgressStatus = (status) => {
      switch (status) {
        case 'completed': return 'success'
        case 'failed': return 'exception'
        case 'paused': return 'warning'
        default: return ''
      }
    }

    const getProgressText = (file) => {
      if (file.status === 'calculating') {
        return `${file.progress}% MD5计算中`
      }
      if (file.status === 'uploading' && file.chunks.length > 0) {
        return `${file.progress}% (${file.uploadedChunks.length}/${file.chunks.length})`
      }
      return `${file.progress}%`
    }

    const calculateSpeed = (file) => {
      if (!file.startTime || file.uploadedBytes === 0) return '0 KB/s'
      const elapsed = (Date.now() - file.startTime) / 1000
      const speed = file.uploadedBytes / elapsed
      return formatFileSize(speed) + '/s'
    }

    const getAlertType = () => {
      if (statusMessage.value.includes('成功') || statusMessage.value.includes('完成')) return 'success'
      if (statusMessage.value.includes('失败') || statusMessage.value.includes('错误')) return 'error'
      if (statusMessage.value.includes('暂停')) return 'warning'
      return 'info'
    }

    // 生命周期
    onMounted(() => {
      initUploadManager()
    })

    onUnmounted(() => {
      if (uploadManager) {
        uploadManager.pauseAllUploads()
      }
    })

    return {
      fileInput,
      fileList,
      showFileList,
      statusMessage,
      isUploading,
      totalProgress,
      hasWaitingFiles,
      hasUploadingFiles,
      hasPausedFiles,
      selectFiles,
      handleFileSelect,
      handleDrop,
      startAllUploads,
      pauseAllUploads,
      resumeAllUploads,
      startSingleUpload,
      pauseSingleUpload,
      resumeSingleUpload,
      removeFile,
      clearAllFiles,
      formatFileSize,
      getStatusText,
      getFileItemClass,
      getProgressStatus,
      getFileProgressStatus,
      getProgressText,
      calculateSpeed,
      getAlertType
    }
  }
}
</script>

<style scoped>
.multi-file-uploader {
  max-width: 1000px;
  margin: 0 auto;
}

.upload-card, .file-list-card {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.upload-area {
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  padding: 60px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
  margin-bottom: 20px;
}

.upload-area:hover {
  border-color: #409EFF;
}

.upload-icon {
  color: #c0c4cc;
  margin-bottom: 16px;
}

.upload-text p {
  margin: 8px 0;
  color: #606266;
}

.upload-hint {
  font-size: 12px;
  color: #c0c4cc;
}

.total-progress {
  margin: 20px 0;
}

.progress-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 14px;
}

.progress-stats {
  color: #909399;
  font-size: 12px;
}

.batch-controls {
  display: flex;
  gap: 10px;
  margin: 20px 0;
  flex-wrap: wrap;
}

.status-message {
  margin: 20px 0;
}

.file-list {
  max-height: 600px;
  overflow-y: auto;
}

.file-item {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  margin-bottom: 10px;
  padding: 15px;
  transition: all 0.3s;
}

.file-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.file-waiting {
  border-left: 4px solid #909399;
}

.file-calculating {
  border-left: 4px solid #e6a23c;
}

.file-uploading {
  border-left: 4px solid #409eff;
}

.file-paused {
  border-left: 4px solid #e6a23c;
}

.file-completed {
  border-left: 4px solid #67c23a;
}

.file-failed {
  border-left: 4px solid #f56c6c;
}

.file-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.file-icon {
  font-size: 24px;
  color: #409eff;
  flex-shrink: 0;
}

.file-details {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-weight: 500;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}

.file-meta {
  font-size: 12px;
  color: #909399;
}

.file-actions {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}

.file-progress {
  margin-top: 12px;
}

.file-error {
  margin-top: 12px;
}

.upload-details {
  margin-top: 8px;
  display: flex;
  gap: 20px;
  font-size: 12px;
  color: #909399;
}

@media (max-width: 768px) {
  .batch-controls {
    flex-direction: column;
  }
  
  .file-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .file-actions {
    align-self: stretch;
    justify-content: space-between;
  }
  
  .upload-details {
    flex-direction: column;
    gap: 4px;
  }
}
</style> 